package com.flow.framework.web.context;

import com.flow.framework.base.properties.component.RequestConfigProperties;
import com.flow.framework.base.properties.component.ResponseConfigProperties;
import com.flow.framework.common.constant.FrameworkCommonConstant;
import com.flow.framework.facade.access.log.opt.annotation.OptLog;
import lombok.Data;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * 请求和响应的上下文信息，该上下文主要是用来辅助记录入访日志的
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2022/12/24
 */
@Data
public class RequestResponseContext {

    /**
     * 请求开始时间戳
     */
    private long startTime;

    /**
     * 原始请求，如果后需包装原始请求，则会把该原始请求替换为包装后的请求
     */
    private HttpServletRequest originalRequest;

    /**
     * 原始响应，如果后需包装原始响应，则会把该原始响应替换为包装后的响应
     */
    private HttpServletResponse originalResponse;

    /**
     * 原始header
     */
    private Map<String, List<String>> originalHeaders;

    /**
     * 请求方式
     */
    private String method;

    /**
     * 请求uri
     */
    private String uri;

    /**
     * 框架对请求处理配置信息
     */
    private RequestConfigProperties requestConfigProperties;

    /**
     * 框架对响应处理配置信息
     */
    private ResponseConfigProperties responseConfigProperties;

    /**
     * 是否在本地记录入访日志
     */
    private boolean enableRecordLocal;

    /**
     * 记录操作日志标识
     */
    private OptLog optLog;

    /**
     * 是否持久化记录入访日志
     */
    private boolean enableRecordPersistence;

    /**
     * 请求的主机地址
     */
    private List<String> remoteHostAddr;

    /**
     * 请求的ContentType
     */
    private String requestContentType;

    /**
     * 请求的body信息，这里只记录字符形式的body
     */
    private String requestBody = FrameworkCommonConstant.EMPTY_STRING;

    /**
     * 响应的ContentType
     */
    private String responseBodyType;

    /**
     * 响应的body信息，这里只记录字符形式的body
     */
    private String responseBody = FrameworkCommonConstant.EMPTY_STRING;

    /**
     * 构造请求和响应的上下文
     *
     * @param startTime               请求开始时间戳
     * @param originalRequest         原始请求
     * @param originalResponse        原始响应
     * @param requestConfigProperties 框架对请求处理配置信息
     * @param responseConfigProperties 框架对响应处理配置信息
     */
    public RequestResponseContext(long startTime, HttpServletRequest originalRequest,
                                  HttpServletResponse originalResponse,
                                  RequestConfigProperties requestConfigProperties,
                                  ResponseConfigProperties responseConfigProperties) {
        this.startTime = startTime;
        this.originalRequest = originalRequest;
        this.originalResponse = originalResponse;
        this.requestConfigProperties = requestConfigProperties;
        this.responseConfigProperties = responseConfigProperties;
    }

    /**
     * 是否需要解构请求body
     *
     * @return 是否需要解构请求body
     */
    public boolean isRequireUnpackRequestBody() {
        return enableRecordLocal || null != optLog || enableRecordPersistence;
    }

    /**
     * 是否需要记录入访日志
     *
     * @return 是否需要解构请求body
     */
    public boolean isRequireRecordTraceLog() {
        return enableRecordLocal || enableRecordPersistence;
    }
}